/**
 * Package:com.goldcitynet.server;
 * $Id: SynManager.java,v 1.3 2009/04/14 13:15:31 yangc Exp $
 * Copyright(c) 2001-2005 www.afteryuan.com
 */
package com.afteryuan.server.thread;

import com.afteryuan.server.SpringContextLoader;
import com.afteryuan.server.data.Sprite;
import com.afteryuan.server.data.SpritePool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.Date;

/**
 * SynManager
 * 同步线程.用户向客户端发送同步信息
 * 同步客户端与服务器端各可移动对象位置
 * 每500毫秒同步一次
 * <p><a href="SynManager.java.html"><i>View Source</i></a></p>
 *
 * @author <a href="mailto:afteryuan@afteryuan.com">$Author: afteryuan $</a>
 * @version $Revision: 1.3 $
 */
public class SynManager extends Thread {
    private static Log log = LogFactory.getLog(SynManager.class);
    /**
     * 时间间隔数量
     */
    public static final int frame = 400;
    /**
     * 时间间隔单位
     */
    public static final int step = 8;

    public static final int stemTime = step * frame;
    public SpritePool spritePool = (SpritePool) SpringContextLoader.getInstance().getBeanFactory().getBean("spritePool");

    /**
     * 同步方法
     * 覆盖Thread类的run方法
     *
     * @see Thread#run()
     */
    public void run() {

        //取出前次当前坐标,判断当前坐标,广播到客户端,更新当前坐标,判断已经走到终点的,踢出movingChararcters

        while (true) {
            long start = new Date().getTime();
            synchronized (spritePool.listOfMoving()) {
                for (Sprite s : spritePool.listOfMoving()) {
                    s.update(stemTime);
                    if (!s.isMoving()) {
                        spritePool.removeFromMoving(s.getId());
                    }
                }
            }

            long end = new Date().getTime();
//            log.debug("同步客户端数量:"+ServerStatus.activedChararcters.size());
            long spend = end - start;

            try {
                long thisTime = frame * step - spend;
                //当thisTime<0时，会有异常使线程中断，造成不能再同步人物坐标.
                if (thisTime > 0) sleep(thisTime);
                else log.error("Error! System is too busy!SynManager thread costed too much time!");
            } catch (InterruptedException e) {
                log.error("The thread synmanager is interrupted!");
                e.printStackTrace();
            } catch (Exception e) {
                log.error("There is an exception unknown be throwed!" + e);
            }
        }
    }
}
